import React, {memo, useEffect, useState} from 'react';

//默认情况下，useEffect的回调函数会在每次渲染时都重新执行，但是这会导致两个问题：
//1.某些代码我们只希望执行一次即可，类似于componentDidMount和componentWillUnmount中完成的事情
//2.另外多次执行也会导致一定的性能问题
const App = memo(() => {
  const [counter, setCounter] = useState(0);
  const [message, setMessage] = useState("Hello World")

  useEffect(() => {
    //情况1: 第二个参数不存在时, 每次渲染时都会执行
    console.log("null, effect执行");

    //每次当前组件卸载重新渲染时都会执行
    return () => {
      console.log("null, 清除函数")
    }
  })

  //useEffect实际上有两个参数：
  //参数一：执行的回调函数
  //参数二：该useEffect在哪些state发生变化时，才重新执行
  useEffect(() => {
    //情况2: 当第二个数组参数为空数组时，effect仅在函数第一次渲染时执行一次
    console.log("[], effect执行")

    //只有当前组件被卸载时执行
    return () => {
      console.log("[], 清除函数")
    }
  }, [])

  useEffect(() => {
    //情况3: 仅在组件第一次渲染和counter发生改变时执行
    console.log("[counter], effect执行")
    document.title = counter;

    //当由 counter 改变引起的卸载重新渲染时，会执行
    return () => {
      console.log("[counter], 清除函数")
    }
  }, [counter])

  useEffect(() => {
    //情况4: 仅在counter或者message发生改变时执行
    console.log("[counter, message], effect执行")

    //当由 counter 或 message 改变引起的卸载重新渲染时，会执行
    return () => {
      console.log("[counter, message], 清除函数")
    }
  }, [counter, message])

  //useEffect可以模拟生命周期，但是它比生命周期更强大、更灵活

  return (
      <div>
        <h2>当前计数：{counter}</h2>
        <button onClick={() => setCounter(counter + 1)}>+1</button>
        <h2>{message}</h2>
        <button onClick={() => setMessage("你好啊，李银河")}>修改文字</button>
      </div>
  );
});

export default App;